﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Devonline.Identity
{
    /// <summary>
    /// 访问控制存储接口
    /// </summary>
    /// <typeparam name="TAccessRule"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    public interface IAccessRuleStore<TAccessRule, TKey> : IDisposable where TAccessRule : class where TKey : IEquatable<TKey>, IConvertible
    {
        /// <summary>
        /// Finds and returns a AccessRule, if any, who has the specified <paramref name="resourceId"/>.
        /// </summary>
        /// <param name="resourceId">The AccessRule id to search for.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
        /// <returns>
        /// The <see cref="Task"/> that represents the asynchronous operation, containing the AccessRule matching the specified <paramref name="resourceId"/> if it exists.
        /// </returns>
        Task<IList<TAccessRule>> GetByResourceIdAsync(TKey resourceId, CancellationToken cancellationToken);

        /// <summary>
        /// Finds and returns a AccessRule, if any, who has the specified <paramref name="assignId"/>.
        /// </summary>
        /// <param name="assignId">The assign id to search for.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
        /// <returns>
        /// The <see cref="Task"/> that represents the asynchronous operation, containing the AccessRule matching the specified <paramref name="assignId"/> if it exists.
        /// </returns>
        Task<IList<TAccessRule>> GetByAssignIdAsync(TKey assignId, CancellationToken cancellationToken);

        /// <summary>
        /// allow a access rule
        /// </summary>
        /// <param name="accessRule">The AccessRule id to search for.</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task Allow(TAccessRule accessRule, CancellationToken cancellationToken);

        /// <summary>
        /// forbid a access rule
        /// </summary>
        /// <param name="accessRule">The AccessRule id to search for.</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task Forbid(TAccessRule accessRule, CancellationToken cancellationToken);

        /// <summary>
        /// set a access rule priority
        /// </summary>
        /// <param name="accessRule">The AccessRule id to search for.</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task SetPriority(TAccessRule accessRule, int priority, CancellationToken cancellationToken);

        /// <summary>
        /// set a access rule condition
        /// </summary>
        /// <param name="accessRule">The AccessRule id to search for.</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task SetCondition(TAccessRule accessRule, string condition, CancellationToken cancellationToken);
    }
}
